package cn.rokhdelar.ams.config.aspect;

import cn.rokhdelar.ams.management.domain.po.SysOperationLog;
import cn.rokhdelar.ams.management.service.SysOperationLogService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.io.Resource;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Arrays;


/**
 * @author Rokhdelar
 * @since 2025/3/24 -- 16:22
 **/
@Aspect
@Component
@RequiredArgsConstructor
public class SysOperationLogAspect {
    private final SysOperationLogService sysOperationLogService;

    @Pointcut("execution(* cn.rokhdelar.ams.*.controller..*(..))")
    public void pointcut() {
    }

    @AfterReturning(pointcut = "pointcut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest request = requestAttributes.getRequest();
            // 获取请求IP、URI、方法名等信息
            String remoteHost = request.getRemoteHost();
            String uri = request.getRequestURI();
            String method = request.getMethod();
            // 获取请求参数
            String params = Arrays.toString(joinPoint.getArgs());
            // 获取用户名
            String username = SecurityContextHolder.getContext().getAuthentication().getName();
            // 获取接口名称
            String function = joinPoint.getTarget().getClass().getSimpleName() + '.' + joinPoint.getSignature().getName();
            // 获取返回结果
            String resultStr = null;
            if (result instanceof Resource || result instanceof byte[] || result instanceof HttpServletResponse) {
                HttpServletResponse response = requestAttributes.getResponse();
                if (response != null) {
                    resultStr = response.getStatus() + "," + "返回结果为二进制文件或流数据，不记录返回值。";
                }
            } else {
                resultStr = result.toString();
            }

            SysOperationLog sysOperationLog = new SysOperationLog();
            sysOperationLog.setIp(remoteHost);
            sysOperationLog.setUsername(username);
            sysOperationLog.setMethod(method);
            sysOperationLog.setParams(params);
            sysOperationLog.setUri(uri);
            sysOperationLog.setInterfaceName(function);
            sysOperationLog.setResult(resultStr);
            sysOperationLog.setOperationTime(LocalDateTime.now());
            sysOperationLogService.save(sysOperationLog);
        }
    }
}
